package com.cq.hd.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cq.hd.common.constant.Constant;
import com.cq.hd.common.constant.MsgConstant;
import com.cq.hd.common.constant.RedisKeyConstant;
import com.cq.hd.common.entity.BusinessInfo;
import com.cq.hd.common.entity.UserInfo;
import com.cq.hd.common.entity.hf.HfBusinessEnterApply;
import com.cq.hd.common.entity.hf.HfBusinessEnterApplyResult;
import com.cq.hd.common.entity.hf.HfBusinessEnterOpenResult;
import com.cq.hd.common.entity.mq.NotifyMsgSendDto;
import com.cq.hd.common.enums.ResponseEnums;
import com.cq.hd.common.enums.biz.*;
import com.cq.hd.common.pagination.Page;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.*;
import com.cq.hd.member.api.dto.*;
import com.cq.hd.member.api.vo.BusinessEnterApplyDetailVo;
import com.cq.hd.member.api.vo.BusinessEnterApplyPageVo;
import com.cq.hd.member.api.vo.BusinessEnterApplyVo;
import com.cq.hd.member.biz.SmsBiz;
import com.cq.hd.member.config.LockUtils;
import com.cq.hd.member.config.WxConfig;
import com.cq.hd.member.mapper.*;
import com.cq.hd.member.mq.provider.BusinessEnterMsgProvider;
import com.cq.hd.member.mq.provider.NotifyMsgProvider;
import com.cq.hd.member.po.*;
import com.cq.hd.member.service.TbBusinessEnterApplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cq.hd.member.service.TbUserBusinessService;
import com.cq.hd.system.api.HfApi;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 商家入驻申请记录表 服务实现类
 * </p>
 *
 * @author mYunYu
 * @since 2023-11-21
 */
@Slf4j
@Service
public class TbBusinessEnterApplyServiceImpl extends ServiceImpl<TbBusinessEnterApplyMapper, TbBusinessEnterApplyPo> implements TbBusinessEnterApplyService {

    @Autowired
    private TbInviteBusinessUrlMapper inviteBusinessUrlMapper;

    @Autowired
    private TbBusinessMapper businessMapper;

    @Autowired
    private TbMerchantMapper merchantMapper;

    @Autowired
    private TbBusinessMerchantMapper businessMerchantMapper;

    @Autowired
    private TbBusinessGroupMapper businessGroupMapper;

    @Autowired
    private TbAdminUserMapper adminUserMapper;

    @Autowired
    private TbBusinessAdminUserMapper businessAdminUserMapper;

    @Autowired
    private TbActiveCountBillMapper activeCountBillMapper;

    @Autowired
    private TbMerchantEnterApplyMapper merchantEnterApplyMapper;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private HfApi hfApi;

    @Autowired
    private WxConfig wxConfig;

    @Autowired
    private SmsBiz smsBiz;

    @Autowired
    private BusinessEnterMsgProvider businessEnterMsgProvider;

    @Autowired
    private NotifyMsgProvider notifyMsgProvider;

    @Autowired
    private TbUserBusinessService userBusinessService;

    @Value("${spring.profiles.active}")
    private String env;

    @Override
    public Page<BusinessEnterApplyPageVo> pageBusinessEnterApply(BusinessEnterApplyPageDto businessEnterApplyPageDto) {
        String startApplyTime = businessEnterApplyPageDto.getStartApplyTime();
        String endApplyTime = businessEnterApplyPageDto.getEndApplyTime();
        String startAuditTime = businessEnterApplyPageDto.getStartAuditTime();
        String endAuditTime = businessEnterApplyPageDto.getEndAuditTime();
        if (!StringUtils.isBlank(startApplyTime) && startApplyTime.length() != 19) {
            Throw.isBusinessException("日期格式错误");
        }
        if (!StringUtils.isBlank(endApplyTime) && endApplyTime.length() != 19) {
            Throw.isBusinessException("日期格式错误");
        }
        if (!StringUtils.isBlank(startAuditTime) && startAuditTime.length() != 19) {
            Throw.isBusinessException("日期格式错误");
        }
        if (!StringUtils.isBlank(endAuditTime) && endAuditTime.length() != 19) {
            Throw.isBusinessException("日期格式错误");
        }

        PageHelper.startPage(businessEnterApplyPageDto.getPageNum(), businessEnterApplyPageDto.getPageSize());
        List<BusinessEnterApplyPageVo> businessEnterApplyPageVos = baseMapper.listBusinessEnterApplyByDto(businessEnterApplyPageDto);
        if (!CollectionUtils.isEmpty(businessEnterApplyPageVos)) {
            for (BusinessEnterApplyPageVo businessEnterApplyPageVo : businessEnterApplyPageVos) {
                // 审核状态（1-待审核，2-已通过，3-未通过，4-待认证）
                Integer auditState = businessEnterApplyPageVo.getAuditState();
                // 系统审核状态
                Integer systemAuditState = businessEnterApplyPageVo.getSystemAuditState();
                if (AuditStateEnum.WAIT_AUDIT.getValue().equals(auditState)) {
                    // 如果是汇付基本信息入驻审核拒绝/汇付商户业务开通审核拒绝/子账户开通审核拒绝/合同签约失败，则处理hf返回的错误信息给前端显示
                    if (SystemAuditStateEnum.HF_ENTER_AUDIT_FAIL.getValue().equals(systemAuditState)
                            || SystemAuditStateEnum.HF_OPEN_AUDIT_FAIL.getValue().equals(systemAuditState)
                            || SystemAuditStateEnum.SUB_ACCOUNT_OPEN_AUDIT_FAIL.getValue().equals(systemAuditState)
                            || SystemAuditStateEnum.CONTRACT_WAIT_SIGN_FAIL.getValue().equals(systemAuditState)) {
                        String hfFailReason = businessEnterApplyPageVo.getHfFailReason();
                        if (!StringUtils.isBlank(hfFailReason)) {
                            try {
                                JSONObject jsonObject = JSON.parseObject(hfFailReason);
                                JSONObject data = jsonObject.getJSONObject("data");
                                businessEnterApplyPageVo.setRefuseReason(data.getString("resp_desc"));
                            } catch (Exception e) {
                                businessEnterApplyPageVo.setRefuseReason(hfFailReason);
                            }
                        }
                    }
                }
            }
        }
        PageInfo<BusinessEnterApplyPageVo> pageInfo = new PageInfo<>(businessEnterApplyPageVos);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public BusinessEnterApplyPageVo details(Long id) {
        TbBusinessEnterApplyPo tbBusinessEnterApplyPo = baseMapper.selectById(id);
        if (tbBusinessEnterApplyPo != null) {
            BusinessEnterApplyPageVo businessEnterApplyPageVo = new BusinessEnterApplyPageVo();
            BeanUtils.copyProperties(tbBusinessEnterApplyPo, businessEnterApplyPageVo);

            // 银行编号
            String bankCode = businessEnterApplyPageVo.getBankCode();
            if (!StringUtils.isBlank(bankCode)) {
                HfBankIdEnum hfBankIdEnum = HfBankIdEnum.typeOfValue(bankCode);
                if (hfBankIdEnum != null) {
                    businessEnterApplyPageVo.setBankName(hfBankIdEnum.getName());
                }
            }

            // 持卡人证件类型
            String certType = businessEnterApplyPageVo.getCertType();
            if (!StringUtils.isBlank(certType)) {
                CertTypeEnum certTypeEnum = CertTypeEnum.typeOfValue(certType);
                if (certTypeEnum != null) {
                    businessEnterApplyPageVo.setCertType(certTypeEnum.getName());
                }
            }

            // 法人证件类型
            String legalCertType = businessEnterApplyPageVo.getLegalCertType();
            if (!StringUtils.isBlank(legalCertType)) {
                CertTypeEnum certTypeEnum = CertTypeEnum.typeOfValue(legalCertType);
                if (certTypeEnum != null) {
                    businessEnterApplyPageVo.setLegalCertType(certTypeEnum.getName());
                }
            }

            return businessEnterApplyPageVo;
        }
        return null;
    }

    @Override
    public boolean audit(BusinessEnterAuditDto businessEnterAuditDto) {
        Integer auditState = businessEnterAuditDto.getAuditState();
        if (auditState == null || AuditStateEnum.typeOf(businessEnterAuditDto.getAuditState()) == null) {
            Throw.isBusinessException("审核状态错误");
        }

        String refuseReason = businessEnterAuditDto.getRefuseReason();
        if (!StringUtils.isBlank(refuseReason) && refuseReason.length() > 50) {
            Throw.isBusinessException("审核拒绝原因最多输入50个字");
        }

        TbBusinessEnterApplyPo tbBusinessEnterApplyPo = baseMapper.selectById(businessEnterAuditDto.getId());
        if (tbBusinessEnterApplyPo == null) {
            Throw.isBusinessException("未找到入驻记录数据");
        }

        if (!AuditStateEnum.WAIT_AUDIT.getValue().equals(tbBusinessEnterApplyPo.getAuditState()) ||
                !SystemAuditStateEnum.MANAGER_WAIT_AUDIT.getValue().equals(tbBusinessEnterApplyPo.getSystemAuditState())) {
            Throw.isBusinessException("入驻记录已被处理");
        }

        if (businessEnterAuditDto.getFinancialAccountType() != null) {
            tbBusinessEnterApplyPo.setFinancialAccountType(businessEnterAuditDto.getFinancialAccountType());
        }

        LocalDateTime now = LocalDateTime.now();

        if (AuditStateEnum.FAIL.getValue().equals(auditState)) {
            tbBusinessEnterApplyPo.setAuditState(AuditStateEnum.FAIL.getValue());
            tbBusinessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.MANAGER_AUDIT_FAIL.getValue());
            tbBusinessEnterApplyPo.setRefuseReason(businessEnterAuditDto.getRefuseReason());
        } else if (AuditStateEnum.SUCCESS.getValue().equals(auditState)) {
            auditPass(tbBusinessEnterApplyPo);
        }

        tbBusinessEnterApplyPo.setAuditTime(now);
        tbBusinessEnterApplyPo.setUpdateTime(now);
        int update = baseMapper.updateById(tbBusinessEnterApplyPo);
        if (update == 0) {
            Throw.isBusinessException("审核入驻记录失败");
        }

        if (AuditStateEnum.SUCCESS.getValue().equals(tbBusinessEnterApplyPo.getAuditState())) {
            businessEnterMsgProvider.sendMsg(tbBusinessEnterApplyPo.getId());
        }

        if (AuditStateEnum.FAIL.getValue().equals(tbBusinessEnterApplyPo.getAuditState())) {
            // 发送商家升级审核结果系统通知
            NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
            notifyMsgSendDto.setUserId(tbBusinessEnterApplyPo.getUserId());
            notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
            notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
            notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.AGENT_BUSINESS_ENTER_AUDIT.getValue());
            notifyMsgSendDto.setContent(MsgConstant.AGENT_BUSINESS_ENTER_AUDIT_FAIL);
            notifyMsgProvider.sendMsg(notifyMsgSendDto);

            // 审核拒绝，发送入驻失败短信
            smsBiz.sendEnterFailSms(tbBusinessEnterApplyPo.getBusinessName(), tbBusinessEnterApplyPo.getMobile());
        }

        return true;
    }

    private void auditPass(TbBusinessEnterApplyPo tbBusinessEnterApplyPo) {
        // 平台统一资金账户，商家不需要再去汇付开通账户
        if (FinancialAccountTypeEnum.PLATFORM.getValue() == tbBusinessEnterApplyPo.getFinancialAccountType()) {
            tbBusinessEnterApplyPo.setAuditState(AuditStateEnum.SUCCESS.getValue());
            enterSuccess(tbBusinessEnterApplyPo.getId());
            return;
        }

        // 测试环境不走汇付
        log.info("商家入驻审核，env:{}", env);

        if ("test".equals(env)) {
            tbBusinessEnterApplyPo.setAuditState(AuditStateEnum.SUCCESS.getValue());
        } else {
            // 提交商家入驻信息给汇付，如果调用接口失败，如果不是处理成功，则提示审核异常，请联系客服，并记录对应的hf原因，否则提示hf对应的错误信息
            HfBusinessEnterApply hfBusinessEnterApply = new HfBusinessEnterApply();
            BeanUtils.copyProperties(tbBusinessEnterApplyPo, hfBusinessEnterApply);
            // 入驻角色类型：1-商家，2-商户
            hfBusinessEnterApply.setEnterType(1);
            HfBusinessEnterApplyResult hfBusinessEnterApplyResult = hfApi.merchantEnt(hfBusinessEnterApply).unpack();
            if (StringUtils.isBlank(hfBusinessEnterApplyResult.getHuiFuId())) {
                log.error("调用汇付商家入驻接口失败，hfId为空，respDesc：{}", hfBusinessEnterApplyResult.getRespDesc());
                Throw.isBusinessException(hfBusinessEnterApplyResult.getRespDesc());
            }

            tbBusinessEnterApplyPo.setHfApplyNo(hfBusinessEnterApplyResult.getApplyNo());
            tbBusinessEnterApplyPo.setHfMerchantNo(hfBusinessEnterApplyResult.getHuiFuId());
            tbBusinessEnterApplyPo.setWithdrawalCardNo(hfBusinessEnterApplyResult.getTokenNo());

            // 如果不为空，表示审核中，如果为空，表示基本信息入驻成功
            String applyNo = hfBusinessEnterApplyResult.getApplyNo();
            if (StringUtils.isBlank(applyNo)) {
                // 基本信息审核成功，调用商户业务开通接口去开通相关业务
                hfBusinessEnterApply = new HfBusinessEnterApply();
                BeanUtils.copyProperties(tbBusinessEnterApplyPo, hfBusinessEnterApply);
                HfBusinessEnterOpenResult hfBusinessEnterOpenResult = hfApi.merchantOpen(hfBusinessEnterApply).unpack();
                if (StringUtils.isBlank(hfBusinessEnterOpenResult.getHuiFuId())) {
                    log.error("后台审核成功，企业基本信息同步审核成功，汇付审核商家入驻成功，调用商户业务开通接口失败，调用接口result：{}", hfBusinessEnterOpenResult.getResultData());

                    // 调用商户业务开通接口失败，系统审核状态=汇付商户业务开通审核拒绝，管理后台核验处理后并再次申请调用
                    tbBusinessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.HF_OPEN_AUDIT_FAIL.getValue());
                    tbBusinessEnterApplyPo.setHfFailReason(hfBusinessEnterOpenResult.getResultData());
                } else {
                    // 调用商户业务开通接口成功，系统审核状态=汇付商户业务开通待审核
                    tbBusinessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.HF_OPEN_WAIT_AUDIT.getValue());
                }
            } else {
                // 基本信息审核中
                tbBusinessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.HF_ENTER_WAIT_AUDIT.getValue());
            }
        }
    }


    @Override
    public Boolean enterSuccess(Long id) {
        TbBusinessEnterApplyPo tbBusinessEnterApplyPo = baseMapper.selectById(id);
        if (tbBusinessEnterApplyPo == null) {
            log.error("商家入驻成功处理商家账号和绑定处理失败，未找到商家入驻申请数据，businessEnterApplyId：{}", id);
            return true;
        }

        // 查询商家是否已经入驻过
        Long userId = tbBusinessEnterApplyPo.getUserId();
        List<TbBusinessPo> businessPos = businessMapper.selectList(new QueryWrapper<TbBusinessPo>().eq("user_id", userId));
        if (!CollectionUtils.isEmpty(businessPos)) {
            log.error("商家入驻成功处理商家账号和绑定处理失败，已经是商家，businessEnterApplyId：{}", id);
            return true;
        }

        Integer auditState = tbBusinessEnterApplyPo.getAuditState();
        // 商家入驻审核成功之后，需要新增商家账号和商户账号数据，并关联，如果商户账号已经存在，则直接关联，并更新最新的用户信息到缓存
        if (!AuditStateEnum.SUCCESS.getValue().equals(auditState)) {
            log.error("商家入驻成功处理商家账号和绑定处理失败，商家入驻申请状态不是审核成功状态，businessEnterApplyId：{}，auditState：{}", id, auditState);
            return true;
        }

        LocalDateTime now = LocalDateUtil.getNowLocalDateTime();
        // 商户/消费者自己升级为商家，赠送次数
        Integer activeCount = Constant.GIVE_ACTIVE_COUNT;
        Integer userCount = 0;
        TbInviteBusinessUrlPo tbInviteBusinessUrlPo = null;
        String settleCode = tbBusinessEnterApplyPo.getSettleCode();
        if (!StringUtils.isBlank(settleCode)) {
            // 查询邀请链接的活动发布次数和经纪人数
            List<TbInviteBusinessUrlPo> tbInviteBusinessUrlPos = inviteBusinessUrlMapper.selectList(new QueryWrapper<TbInviteBusinessUrlPo>().eq("del_state", 0)
                    .eq("invite_code", tbBusinessEnterApplyPo.getSettleCode()));
            tbInviteBusinessUrlPo = tbInviteBusinessUrlPos.get(0);
            // 默认送次卡2次，加上链接设置的次数
            activeCount += tbInviteBusinessUrlPo.getActiveCount();
            userCount = tbInviteBusinessUrlPo.getUserCount();
        }

        // 生成邀请码
        String inviteCode;
        while (true) {
            inviteCode = NoUtils.getBusinessInviteCode();
            Integer count = businessMapper.selectCount(new QueryWrapper<TbBusinessPo>().eq("del_state", 0)
                    .eq("invite_code", inviteCode));
            if (count == null || count == 0) {
                break;
            }
        }

        TbMerchantPo tbMerchantPo = null;
        // 根据手机号查询商户账号，如果存在
        List<TbMerchantPo> merchantPos = merchantMapper.selectList(new QueryWrapper<TbMerchantPo>().eq("mobile", tbBusinessEnterApplyPo.getMobile()));
        if (!CollectionUtils.isEmpty(merchantPos)) {
            tbMerchantPo = merchantPos.get(0);
        }

        // 新增商家账号tb_business
        TbBusinessPo tbBusinessPo = new TbBusinessPo();
        BeanUtils.copyProperties(tbBusinessEnterApplyPo, tbBusinessPo);
        tbBusinessPo.setBusinessNo(NoUtils.getBusinessNo());
        tbBusinessPo.setHfAcctId(tbBusinessEnterApplyPo.getHfAcctId());
        tbBusinessPo.setOpenid(tbBusinessEnterApplyPo.getOpenid());
        // 定位取的是线下场所地址
        tbBusinessPo.setPosition(tbBusinessEnterApplyPo.getBusinessAddress());
        tbBusinessPo.setProvinceName(tbBusinessEnterApplyPo.getBusinessProvinceName());
        tbBusinessPo.setCityName(tbBusinessEnterApplyPo.getBusinessCityName());
        tbBusinessPo.setCountyName(tbBusinessEnterApplyPo.getBusinessCountyName());
        tbBusinessPo.setInviteCode(inviteCode);
        tbBusinessPo.setActiveCount(activeCount);
        tbBusinessPo.setAgentCount(userCount);
        // 商家状态（1-正常，2-试用中，3-已过期）
        tbBusinessPo.setState(1);
        tbBusinessPo.setSubsidyAmt(BigDecimal.ZERO);
        tbBusinessPo.setFreezeAmt(BigDecimal.ZERO);
        tbBusinessPo.setCreateTime(now);

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        try {
            int count = businessMapper.insert(tbBusinessPo);
            if (count == 0) {
                log.error("新增商家账号失败");
                Throw.isBusinessException("审核入驻记录失败");
            }
            Long businessId = tbBusinessPo.getId();

            // 新增商户账号tb_merchant
            if (tbMerchantPo == null) {
                tbMerchantPo = new TbMerchantPo();
                BeanUtils.copyProperties(tbBusinessEnterApplyPo, tbMerchantPo);
                tbMerchantPo.setMerchantNo(NoUtils.getMerchantNo());
                tbMerchantPo.setSettleCode(inviteCode);
                if (!StringUtils.isBlank(tbBusinessEnterApplyPo.getHfAcctId())) {
                    tbMerchantPo.setHfMerchantNo(tbBusinessEnterApplyPo.getHfAcctId());
                }
                tbMerchantPo.setOpenid(tbBusinessEnterApplyPo.getOpenid());
                tbMerchantPo.setNickName(tbBusinessPo.getBusinessShortName());
                tbMerchantPo.setAvatar(tbBusinessPo.getLogo());
                tbMerchantPo.setMerchantName(tbBusinessPo.getBusinessName());
                tbMerchantPo.setMerchantShortName(tbBusinessPo.getBusinessShortName());
                tbMerchantPo.setProvinceName(tbBusinessPo.getProvinceName());
                tbMerchantPo.setCityName(tbBusinessPo.getCityName());
                tbMerchantPo.setCountyName(tbBusinessPo.getCountyName());
                tbMerchantPo.setPosition(tbBusinessPo.getPosition());
                // 状态(1-正常，2-已封禁)
                tbMerchantPo.setState(1);
                tbMerchantPo.setBalanceAmt(BigDecimal.ZERO);
                tbMerchantPo.setFreezeAmt(BigDecimal.ZERO);
                tbMerchantPo.setCreateTime(now);
                count = merchantMapper.insert(tbMerchantPo);
                if (count == 0) {
                    log.error("新增商户账号失败");
                    Throw.isBusinessException("审核入驻记录失败");
                }
            }
            Long merchantId = tbMerchantPo.getId();

            // 新增关联tb_business_merchant
            TbBusinessMerchantPo tbBusinessMerchantPo = new TbBusinessMerchantPo();
            tbBusinessMerchantPo.setMerchantId(merchantId);
            tbBusinessMerchantPo.setBusinessId(businessId);
            tbBusinessMerchantPo.setTotalOrderCount(0);
            tbBusinessMerchantPo.setTotalOrderAmt(BigDecimal.ZERO);
            tbBusinessMerchantPo.setTotalSubsidyAmt(BigDecimal.ZERO);
            // 是否是商家自有商户：1-否，2-是
            tbBusinessMerchantPo.setOwnState(OwnStateEnum.YES.getValue());
            tbBusinessMerchantPo.setCreateTime(now);
            count = businessMerchantMapper.insert(tbBusinessMerchantPo);
            if (count == 0) {
                log.error("新增商户商家关联数据失败");
                Throw.isBusinessException("审核入驻记录失败");
            }

            // 新增后台用户账号
            TbAdminUserPo tbAdminUserPo = new TbAdminUserPo();
            tbAdminUserPo.setUserName(tbBusinessPo.getBusinessName());
            tbAdminUserPo.setMobile(tbBusinessPo.getMobile());
            tbAdminUserPo.setAvatar(tbBusinessPo.getLogo());
            // 商家角色id
            tbAdminUserPo.setRoleId(Constant.BUSINESS_ROLE_ID);
            tbAdminUserPo.setStatus(0);
            tbAdminUserPo.setCreateTime(now);
            tbAdminUserPo.setUpdateTime(now);
            count = adminUserMapper.insert(tbAdminUserPo);
            if (count == 0) {
                log.error("新增后台商家用户数据失败");
                Throw.isBusinessException("审核入驻记录失败");
            }
            Integer adminUserId = tbAdminUserPo.getId();

            // 新增商家关联后台账号
            TbBusinessAdminUserPo tbBusinessAdminUserPo = new TbBusinessAdminUserPo();
            tbBusinessAdminUserPo.setAppUserId(tbBusinessPo.getUserId());
            tbBusinessAdminUserPo.setBusinessId(businessId);
            tbBusinessAdminUserPo.setAdminUserId(adminUserId);
            tbBusinessAdminUserPo.setCreateTime(now);
            tbBusinessAdminUserPo.setUpdateTime(now);
            count = businessAdminUserMapper.insert(tbBusinessAdminUserPo);
            if (count == 0) {
                log.error("新增商家关联后台账号数据失败");
                Throw.isBusinessException("审核入驻记录失败");
            }

            // 更新邀请链接的成功入驻数
            if (tbInviteBusinessUrlPo != null) {
                count = inviteBusinessUrlMapper.addSettleSuccessCount(tbInviteBusinessUrlPo.getId(), 1);
                if (count == 0) {
                    log.error("更新邀请链接的成功入驻数失败");
                    Throw.isBusinessException("审核入驻记录失败");
                }
            }

            // 新增默认分组，分组名称=未分组
            TbBusinessGroupPo tbBusinessGroupPo = new TbBusinessGroupPo();
            tbBusinessGroupPo.setBusinessId(businessId);
            tbBusinessGroupPo.setAgentId(0L);
            tbBusinessGroupPo.setGroupName("未分组");
            tbBusinessGroupPo.setDefaultState(BusinessGroupDefaultStateEnum.YES.getValue());
            tbBusinessGroupPo.setNum(0);
            tbBusinessGroupPo.setCommissionRate(BigDecimal.ZERO);
            tbBusinessGroupPo.setCreateTime(now);
            tbBusinessGroupPo.setUpdateTime(now);
            count = businessGroupMapper.insert(tbBusinessGroupPo);
            if (count == 0) {
                log.error("新增商家默认分组失败");
                Throw.isBusinessException("审核入驻记录失败");
            }

            // 新增活动次数流水
            TbActiveCountBillPo tbActiveCountBillPo = new TbActiveCountBillPo();
            tbActiveCountBillPo.setBusinessId(businessId);
            tbActiveCountBillPo.setUserId(tbBusinessPo.getUserId());
            tbActiveCountBillPo.setBillType(BillTypeEnum.INCOME.getValue());
            tbActiveCountBillPo.setTradeType(ActiveCountTradeTypeEnum.OWN_ENTER.getValue());
            tbActiveCountBillPo.setTradeCount(activeCount);
            if (tbInviteBusinessUrlPo != null) {
                tbActiveCountBillPo.setTradeType(ActiveCountTradeTypeEnum.INVITE_URL_ENTER.getValue());
                tbActiveCountBillPo.setRelationId(tbInviteBusinessUrlPo.getId());
            }
            tbActiveCountBillPo.setTradeTime(now);
            tbActiveCountBillPo.setCreateTime(now);
            tbActiveCountBillPo.setUpdateTime(now);
            count = activeCountBillMapper.insert(tbActiveCountBillPo);
            if (count == 0) {
                log.error("新增活动次数流水失败");
                Throw.isBusinessException("审核入驻记录失败");
            }

            // 增加用户-商家关联表
            userBusinessService.related(userId, businessId);

            transactionManager.commit(transaction);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(transaction);
            log.error("<商家入驻成功处理商家账号和绑定>事务异常回滚", e);
            Throw.isBusinessException(e.getMessage());
        }

        // 将最新的用户数据缓存Redis
        String userInfoRedis = redisUtil.get(String.format(RedisKeyConstant.USER_INFO_KEY, tbBusinessEnterApplyPo.getUserId()));
        if (!StringUtils.isNullOrEmpty(userInfoRedis)) {
            UserInfo userInfo = JSON.parseObject(userInfoRedis, UserInfo.class);
            BusinessInfo businessInfo = new BusinessInfo();
            BeanUtils.copyProperties(tbBusinessPo, businessInfo);
            userInfo.setBusinessInfo(businessInfo);

            redisUtil.set(String.format(RedisKeyConstant.USER_INFO_KEY, tbBusinessEnterApplyPo.getUserId()), JSON.toJSONString(userInfo), Constant.USER_LOGIN_TIMEOUT, TimeUnit.SECONDS);
        }

        // 发送商家入驻成功的短信
        Boolean sendState = smsBiz.sendEnterSuccessSms(tbBusinessPo.getBusinessName(), tbBusinessPo.getMobile());
        if (!sendState) {
            log.error("发送商家入驻成功的短信失败，mobile：{}", tbBusinessPo.getMobile());
        }

        // 发送商家升级审核结果系统通知
        NotifyMsgSendDto notifyMsgSendDto = new NotifyMsgSendDto();
        notifyMsgSendDto.setUserId(tbBusinessEnterApplyPo.getUserId());
        notifyMsgSendDto.setMsgState(NotifyMsgStateEnum.NO_READ.getValue());
        notifyMsgSendDto.setRoleType(RoleTypeEnum.BUSINESS.getValue());
        notifyMsgSendDto.setMsgType(NotifyMsgTypeEnum.AGENT_BUSINESS_ENTER_AUDIT.getValue());
        notifyMsgSendDto.setContent(MsgConstant.AGENT_BUSINESS_ENTER_AUDIT_SUCCESS);
        notifyMsgProvider.sendMsg(notifyMsgSendDto);

        return true;
    }

    @Override
    public boolean apply(BusinessEnterApplyDto businessEnterApplyDto) {
        String openid = businessEnterApplyDto.getOpenid();
        if (StringUtils.isBlank(openid)) {
            Throw.isBusinessException("请先授权");
        }

        String mobile = businessEnterApplyDto.getMobile();
        if (StringUtils.isBlank(mobile)) {
            Throw.isBusinessException("请授权手机号");
        }

        // 对入驻的手机号加锁
        String lockKey = MessageFormat.format(Constant.LOCK_FORMAT, "businessEnterApply:" + mobile);
        try {
            LockUtils.blockLock(lockKey, Constant.AUTO_UNLOCK_SECOND);

            // 校验入驻信息是否正确
            validEnterApplyInfo(businessEnterApplyDto);

            // 商家简称唯一
            String businessShortName = businessEnterApplyDto.getBusinessShortName();
            Integer businessShortNameCount = businessMapper.selectCount(new QueryWrapper<TbBusinessPo>()
                    .eq("business_short_name", businessShortName));
            if (businessShortNameCount != null && businessShortNameCount > 0) {
                Throw.isBusinessException("商家简称已存在");
            }

            LocalDateTime now = LocalDateTime.now();

            String settleCode = businessEnterApplyDto.getSettleCode();
            if (!StringUtils.isBlank(settleCode)) {
                List<TbInviteBusinessUrlPo> tbInviteBusinessUrlPos = inviteBusinessUrlMapper.selectList(new QueryWrapper<TbInviteBusinessUrlPo>().eq("del_state", 0)
                        .eq("invite_code", settleCode));
                if (CollectionUtils.isEmpty(tbInviteBusinessUrlPos)) {
                    Throw.isBusinessException(ResponseEnums.BUSINESS_INVITATION_URL_FAILED);
                }

                TbInviteBusinessUrlPo tbInviteBusinessUrlPo = tbInviteBusinessUrlPos.get(0);
                if (!now.isBefore(tbInviteBusinessUrlPo.getExpireTime())) {
                    Throw.isBusinessException(ResponseEnums.BUSINESS_INVITATION_URL_FAILED);
                }
            }

            // 每个手机号只能存在一条商家数据
            Integer count = businessMapper.selectCount(new QueryWrapper<TbBusinessPo>()
                    .eq("mobile", mobile));
            if (count != null && count > 0) {
                Throw.isBusinessException("手机号已被使用，请更换手机号");
            }

            // 判断是否存在手机号待审核or审核成功的商户申请入驻记录
            List<TbMerchantEnterApplyPo> tbMerchantEnterApplyPos = merchantEnterApplyMapper.selectList(new QueryWrapper<TbMerchantEnterApplyPo>().eq("del_state", 0)
                    .eq("mobile", mobile)
                    .in("audit_state", Arrays.asList(AuditStateEnum.WAIT_AUDIT.getValue(), AuditStateEnum.WAIT_AUTH.getValue())));
            if (!CollectionUtils.isEmpty(tbMerchantEnterApplyPos)) {
                // 如果存在待审核的入驻记录，则不能申请入驻
                Throw.isBusinessException("手机号已被使用，请更换手机号");
            }

            // 判断是否存在手机号待审核or审核成功的商家申请入驻记录
            List<TbBusinessEnterApplyPo> businessEnterApplyPos = baseMapper.selectList(new QueryWrapper<TbBusinessEnterApplyPo>().eq("del_state", 0)
                    .eq("mobile", mobile)
                    .in("audit_state", Arrays.asList(AuditStateEnum.WAIT_AUDIT.getValue(), AuditStateEnum.WAIT_AUTH.getValue(), AuditStateEnum.SUCCESS.getValue())));
            if (!CollectionUtils.isEmpty(businessEnterApplyPos)) {
//            List<TbBusinessEnterApplyPo> successMerchantEnterApplyList = businessEnterApplyPos.stream()
//                    .filter(merchantEnterApplyPo -> AuditStateEnum.SUCCESS.getValue().equals(merchantEnterApplyPo.getAuditState())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(businessEnterApplyPos)) {
                    Throw.isBusinessException("手机号已被使用，请更换手机号");
                }

//            List<TbBusinessEnterApplyPo> waitMerchantEnterApplyList = businessEnterApplyPos.stream()
//                    .filter(merchantEnterApplyPo -> (AuditStateEnum.WAIT_AUDIT.getValue().equals(merchantEnterApplyPo.getAuditState())
//                            || AuditStateEnum.WAIT_AUTH.getValue().equals(merchantEnterApplyPo.getAuditState())))
//                    .collect(Collectors.toList());
//            if (!CollectionUtils.isEmpty(waitMerchantEnterApplyList)) {
//                if (!StringUtils.isBlank(settleCode)) {
//                    for (TbBusinessEnterApplyPo tbBusinessEnterApplyPo : waitMerchantEnterApplyList) {
//                        // 不是同个链接下的同个手机号申请入驻
//                        if (!settleCode.equals(tbBusinessEnterApplyPo.getSettleCode())) {
//                            Throw.isBusinessException("手机号已被使用，请更换手机号");
//                        }
//                    }
//                }
//
//                Throw.isBusinessException("你已提交入驻申请，正在审核中");
//            }
            }

            // 每个用户只能存在一条待审核的入驻记录
            Integer applyCount = baseMapper.selectCount(new QueryWrapper<TbBusinessEnterApplyPo>().eq("del_state", 0)
                    .eq("user_id", businessEnterApplyDto.getUserId())
                    .eq("audit_state", Arrays.asList(AuditStateEnum.WAIT_AUDIT.getValue(), AuditStateEnum.WAIT_AUTH.getValue())));
            if (applyCount != null && applyCount > 0) {
                Throw.isBusinessException("你入驻申请的记录正在审核中，请稍后");
            }

            // 如果用户已经是商家，则不能申请商家入驻
            Integer businessCount = businessMapper.selectCount(new QueryWrapper<TbBusinessPo>().eq("del_state", 0)
                    .eq("user_id", businessEnterApplyDto.getUserId()));
            if (businessCount != null && businessCount > 0) {
                Throw.isBusinessException("你已经是商家，不能申请入驻");
            }

            TbBusinessEnterApplyPo tbBusinessEnterApplyPo = new TbBusinessEnterApplyPo();
            BeanUtils.copyProperties(businessEnterApplyDto, tbBusinessEnterApplyPo);
            tbBusinessEnterApplyPo.setApplyNo(NoUtils.getBusinessEnterApplyNo());
            tbBusinessEnterApplyPo.setApplyTime(now);
            tbBusinessEnterApplyPo.setAuditState(AuditStateEnum.WAIT_AUDIT.getValue());
            tbBusinessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.MANAGER_WAIT_AUDIT.getValue());
            tbBusinessEnterApplyPo.setCreateTime(now);
            int insert = baseMapper.insert(tbBusinessEnterApplyPo);
            if (insert == 0) {
                Throw.isBusinessException("商家入驻申请失败");
            }

            return true;
        } finally {
            LockUtils.unlock(lockKey);
        }
    }

    private void validEnterApplyInfo(BusinessEnterApplyDto businessEnterApplyDto) {
        String businessName = businessEnterApplyDto.getBusinessName();
        if (StringUtils.isBlank(businessName)) {
            Throw.isBusinessException("请输入商家名称");
        }

        String businessShortName = businessEnterApplyDto.getBusinessShortName();
        if (StringUtils.isBlank(businessShortName)) {
            Throw.isBusinessException("请输入商家简称");
        }

        Integer companyType = businessEnterApplyDto.getCompanyType();
        if (companyType == null || CompanyTypeEnum.typeOf(companyType) == null) {
            Throw.isBusinessException("请选择公司类型");
        }

        String logo = businessEnterApplyDto.getLogo();
        if (StringUtils.isBlank(logo)) {
            Throw.isBusinessException("请上传商家logo");
        }

        Long mccOneId = businessEnterApplyDto.getMccOneId();
        Long mccTwoId = businessEnterApplyDto.getMccTwoId();
        String mcc = businessEnterApplyDto.getMcc();
        String mccName = businessEnterApplyDto.getMccName();
        if (mccOneId == null || mccTwoId == null && StringUtils.isBlank(mcc) || StringUtils.isBlank(mccName)) {
            Throw.isBusinessException("请选择所属行业");
        }

        if (StringUtils.isBlank(businessEnterApplyDto.getLicensePic()) || StringUtils.isBlank(businessEnterApplyDto.getLicensePicUrl())) {
            Throw.isBusinessException("请上传营业执照");
        }

        Integer licenseValidityType = businessEnterApplyDto.getLicenseValidityType();
        if (licenseValidityType == null || CertValidityTypeEnum.typeOfValue(licenseValidityType) == null) {
            Throw.isBusinessException("请选择营业执照有效期");
        }

        if (CertValidityTypeEnum.NO.getValue().equals(licenseValidityType)) {
            String licenseBeginDate = businessEnterApplyDto.getLicenseBeginDate();
            String licenseEndDate = businessEnterApplyDto.getLicenseEndDate();
            if (StringUtils.isBlank(licenseBeginDate)) {
                Throw.isBusinessException("请选择营业执照有效期开始日期");
            }

            if (StringUtils.isBlank(licenseEndDate)) {
                Throw.isBusinessException("请选择营业执照有效期截止日期");
            }

            LocalDate licenseBeginLocalDate = null;
            LocalDate licenseEndLocalDate = null;
            try {
                licenseBeginLocalDate = LocalDateUtil.toLocalDate(licenseBeginDate, Constant.YYYY_MM_DD);
            } catch (Exception e) {
                Throw.isBusinessException("营业执照有效期开始日期选择错误");
            }

            try {
                licenseEndLocalDate = LocalDateUtil.toLocalDate(licenseEndDate, Constant.YYYY_MM_DD);
            } catch (Exception e) {
                Throw.isBusinessException("营业执照有效期截止日期选择错误");
            }

            if (licenseEndLocalDate.compareTo(licenseBeginLocalDate) <= 0) {
                Throw.isBusinessException("营业执照有效期截止日期必须大于开始日期");
            }
        } else {
            // 如果是长期有效，营业执照有效期开始日期也不能为空
            String licenseBeginDate = businessEnterApplyDto.getLicenseBeginDate();
            if (StringUtils.isBlank(licenseBeginDate)) {
                Throw.isBusinessException("请选择营业执照有效期开始日期");
            }

            LocalDate licenseBeginLocalDate = null;
            try {
                licenseBeginLocalDate = LocalDateUtil.toLocalDate(licenseBeginDate, Constant.YYYY_MM_DD);
            } catch (Exception e) {
                Throw.isBusinessException("营业执照有效期开始日期选择错误");
            }
        }

        String foundDate = businessEnterApplyDto.getFoundDate();
        if (StringUtils.isBlank(foundDate)) {
            Throw.isBusinessException("请选择成立时间");
        }

        try {
            LocalDateUtil.toLocalDate(foundDate, Constant.YYYY_MM_DD);
        } catch (Exception e) {
            Throw.isBusinessException("成立时间选择错误");
        }

        // 保留两位小数；条件选填，国营企业、私营企业、外资企业、事业单位、其他、集体经济必填，政府机构、个体工商户可为空
        BigDecimal regCapital = businessEnterApplyDto.getRegCapital();
        if (!CompanyTypeEnum.GTGSH.getValue().equals(companyType) && !CompanyTypeEnum.ZFJG.getValue().equals(companyType)) {
            if (regCapital == null || regCapital.compareTo(BigDecimal.ZERO) <= 0) {
                Throw.isBusinessException("请输入注册资本");
            }
        }

        String businessScope = businessEnterApplyDto.getBusinessScope();
        if (StringUtils.isBlank(businessScope)) {
            Throw.isBusinessException("请输入经营范围");
        }

        String regProvinceName = businessEnterApplyDto.getRegProvinceName();
        String regProvinceCode = businessEnterApplyDto.getRegProvinceCode();
        String regCityName = businessEnterApplyDto.getRegCityName();
        String regCityCode = businessEnterApplyDto.getRegCityCode();
        String regCountyName = businessEnterApplyDto.getRegCountyName();
        String regCountyCode = businessEnterApplyDto.getRegCountyCode();
        if (StringUtils.isBlank(regProvinceName) || StringUtils.isBlank(regProvinceCode)) {
            Throw.isBusinessException("请选择注册省份");
        }

        if (StringUtils.isBlank(regCityName) || StringUtils.isBlank(regCityCode)) {
            Throw.isBusinessException("请选择注册市");
        }

        if (StringUtils.isBlank(regCountyName) || StringUtils.isBlank(regCountyCode)) {
            Throw.isBusinessException("请选择注册区县");
        }

        String regAddress = businessEnterApplyDto.getRegAddress();
        if (StringUtils.isBlank(regAddress)) {
            Throw.isBusinessException("请输入注册详细地址");
        }

        String businessProvinceName = businessEnterApplyDto.getBusinessProvinceName();
        String businessProvinceCode = businessEnterApplyDto.getBusinessProvinceCode();
        String businessCityName = businessEnterApplyDto.getBusinessCityName();
        String businessCityCode = businessEnterApplyDto.getBusinessCityCode();
        String businessCountyName = businessEnterApplyDto.getBusinessCountyName();
        String businessCountyCode = businessEnterApplyDto.getBusinessCountyCode();

        if (StringUtils.isBlank(businessProvinceName) || StringUtils.isBlank(businessProvinceCode)) {
            Throw.isBusinessException("请选择经营省份");
        }

        if (StringUtils.isBlank(businessCityName) || StringUtils.isBlank(businessCityCode)) {
            Throw.isBusinessException("请选择经营市");
        }

        if (StringUtils.isBlank(businessCountyName) || StringUtils.isBlank(businessCountyCode)) {
            Throw.isBusinessException("请选择经营区县");
        }

        String businessAddress = businessEnterApplyDto.getBusinessAddress();
        if (StringUtils.isBlank(businessAddress)) {
            Throw.isBusinessException("请输入经营详细地址");
        }

        String customerMobile = businessEnterApplyDto.getCustomerMobile();
        if (StringUtils.isBlank(customerMobile)) {
            Throw.isBusinessException("请输入客服电话");
        }

        String contactName = businessEnterApplyDto.getContactName();
        if (StringUtils.isBlank(contactName)) {
            Throw.isBusinessException("请输入联系人姓名");
        }

        String contactMobileNo = businessEnterApplyDto.getContactMobileNo();
        if (StringUtils.isBlank(contactMobileNo)) {
            Throw.isBusinessException("请输入联系人手机号");
        }

        String contactEmail = businessEnterApplyDto.getContactEmail();
        if (StringUtils.isBlank(contactEmail)) {
            Throw.isBusinessException("请输入联系人电子邮箱");
        }

        if (StringUtils.isBlank(businessEnterApplyDto.getStoreHeaderPic()) || StringUtils.isBlank(businessEnterApplyDto.getStoreHeaderPicUrl())) {
            Throw.isBusinessException("请上传线下经营-门头照");
        }

        if (StringUtils.isBlank(businessEnterApplyDto.getStoreIndoorPic()) || StringUtils.isBlank(businessEnterApplyDto.getStoreIndoorPicUrl())) {
            Throw.isBusinessException("请上传线下经营-内景照");
        }

        if (StringUtils.isBlank(businessEnterApplyDto.getStoreCashierDeskPic()) || StringUtils.isBlank(businessEnterApplyDto.getStoreCashierDeskPicUrl())) {
            Throw.isBusinessException("请上传线下经营-收银台");
        }

        String legalName = businessEnterApplyDto.getLegalName();
        if (StringUtils.isBlank(legalName)) {
            Throw.isBusinessException("请输入法人姓名");
        }

        String legalCertType = businessEnterApplyDto.getLegalCertType();
        if (StringUtils.isBlank(legalCertType) || CertTypeEnum.typeOfValue(legalCertType) == null) {
            Throw.isBusinessException("请输入法人证件类型");
        }

        String legalCertNo = businessEnterApplyDto.getLegalCertNo();
        if (StringUtils.isBlank(legalCertNo)) {
            Throw.isBusinessException("请输入法人证件号码");
        }

        Integer legalCertValidityType = businessEnterApplyDto.getLegalCertValidityType();
        if (legalCertValidityType == null || CertValidityTypeEnum.typeOfValue(legalCertValidityType) == null) {
            Throw.isBusinessException("请选择法人证件有效期");
        }

        if (CertValidityTypeEnum.NO.getValue().equals(legalCertValidityType)) {
            String legalCertBeginDate = businessEnterApplyDto.getLegalCertBeginDate();
            String legalCertEndDate = businessEnterApplyDto.getLegalCertEndDate();
            if (StringUtils.isBlank(legalCertBeginDate)) {
                Throw.isBusinessException("请选择法人证件有效期开始日期");
            }

            if (StringUtils.isBlank(legalCertEndDate)) {
                Throw.isBusinessException("请选择法人证件有效期截止日期");
            }

            LocalDate legalCertBeginLocalDate = null;
            LocalDate legalCertEndLocalDate = null;
            try {
                legalCertBeginLocalDate = LocalDateUtil.toLocalDate(legalCertBeginDate, Constant.YYYY_MM_DD);
            } catch (Exception e) {
                Throw.isBusinessException("法人证件有效期开始日期选择错误");
            }

            try {
                legalCertEndLocalDate = LocalDateUtil.toLocalDate(legalCertEndDate, Constant.YYYY_MM_DD);
            } catch (Exception e) {
                Throw.isBusinessException("法人证件有效期截止日期选择错误");
            }

            if (legalCertEndLocalDate.compareTo(legalCertBeginLocalDate) <= 0) {
                Throw.isBusinessException("法人证件有效期截止日期必须大于开始日期");
            }
        } else {
            // 如果是长期有效，法人证件有效期开始日期也不能为空
            String legalCertBeginDate = businessEnterApplyDto.getLegalCertBeginDate();
            if (StringUtils.isBlank(legalCertBeginDate)) {
                Throw.isBusinessException("请选择法人证件有效期开始日期");
            }

            LocalDate legalCertBeginLocalDate = null;
            try {
                legalCertBeginLocalDate = LocalDateUtil.toLocalDate(legalCertBeginDate, Constant.YYYY_MM_DD);
            } catch (Exception e) {
                Throw.isBusinessException("法人证件有效期开始日期选择错误");
            }
        }

        String legalMobileNo = businessEnterApplyDto.getLegalMobileNo();
        if (StringUtils.isBlank(legalMobileNo)) {
            Throw.isBusinessException("请输入法人手机号");
        }

        String legalAddr = businessEnterApplyDto.getLegalAddr();
        if (StringUtils.isBlank(legalAddr)) {
            Throw.isBusinessException("请输入法人身份证地址");
        }

        if (StringUtils.isBlank(businessEnterApplyDto.getLegalCertFrontPic()) || StringUtils.isBlank(businessEnterApplyDto.getLegalCertFrontPicUrl())) {
            Throw.isBusinessException("请上传法人身份证人像面");
        }

        if (StringUtils.isBlank(businessEnterApplyDto.getLegalCertBackPic()) || StringUtils.isBlank(businessEnterApplyDto.getLegalCertBackPicUrl())) {
            Throw.isBusinessException("请上传法人身份证国徽面");
        }

        Integer signUserType = businessEnterApplyDto.getSignUserType();
        if (signUserType == null || SignUserTypeEnum.typeOfValue(signUserType) == null) {
            Throw.isBusinessException("请选择签约人");
        }

        String contactCertNo = businessEnterApplyDto.getContactCertNo();
        if (SignUserTypeEnum.CONTACT.getValue().equals(signUserType) && StringUtils.isBlank(contactCertNo)) {
            Throw.isBusinessException("请填写联系人身份证号");
        }

        Integer cardType = businessEnterApplyDto.getCardType();
        if (cardType == null || CardTypeEnum.typeOfValue(cardType) == null) {
            Throw.isBusinessException("请选择账户类型");
        }

        if (CardTypeEnum.DG.getValue().equals(cardType)) {
            // 对公账户
            if (StringUtils.isBlank(businessEnterApplyDto.getRegAcctPic()) || StringUtils.isBlank(businessEnterApplyDto.getRegAcctPicUrl())) {
                Throw.isBusinessException("请上传开户许可证");
            }

            // 当注册地址或经营地址为如下地区时必填：浙江,海南,重庆,河南,江苏,宁波市,黑龙江,吉林,湖南,贵州,陕西,湖北
            // 当注册地址或经营地址为如下地区时必填：江苏省、浙江省、湖南省、湖北省、云南省、贵州省、陕西省、河南省、吉林省、黑龙江省、福建省、海南省、重庆市、青海省、宁夏回族自治区；
//            if (businessProvinceName.contains("江苏") || businessProvinceName.contains("浙江") || businessProvinceName.contains("湖南")
//                    || businessProvinceName.contains("湖北") || businessProvinceName.contains("云南") || businessProvinceName.contains("贵州")
//                    || businessProvinceName.contains("陕西") || businessProvinceName.contains("河南") || businessProvinceName.contains("吉林")
//                    || businessProvinceName.contains("黑龙江") || businessProvinceName.contains("福建") || businessProvinceName.contains("海南")
//                    || businessProvinceName.contains("重庆") || businessProvinceName.contains("青海") || businessProvinceName.contains("宁夏")) {
            String openLicenceNo = businessEnterApplyDto.getOpenLicenceNo();
            if (StringUtils.isBlank(openLicenceNo)) {
                Throw.isBusinessException("请填写开户许可证核准号");
            }
//            }

            String branchCode = businessEnterApplyDto.getBranchCode();
            if (StringUtils.isBlank(branchCode)) {
                Throw.isBusinessException("请填写联行号");
            }

            // 银行编号
//            String bankCode = businessEnterApplyDto.getBankCode();
//            if (StringUtils.isBlank(bankCode)) {
//                Throw.isBusinessException("请选择银行");
//            }
//
//            // 支行名称
//            String branchName = businessEnterApplyDto.getBranchName();
//            if (StringUtils.isBlank(branchName)) {
//                Throw.isBusinessException("请填写开户支行名称");
//            }
        } else if (CardTypeEnum.DS.getValue().equals(cardType)) {
            // 对私法人账户
            String certType = businessEnterApplyDto.getCertType();
            if (certType == null || CertTypeEnum.typeOfValue(certType) == null) {
                Throw.isBusinessException("请选择持卡人证件类型");
            }

            String certNo = businessEnterApplyDto.getCertNo();
            if (StringUtils.isBlank(certNo)) {
                Throw.isBusinessException("请选择持卡人证件号码");
            }

            Integer certValidityType = businessEnterApplyDto.getCertValidityType();
            if (certValidityType == null || CertValidityTypeEnum.typeOfValue(certValidityType) == null) {
                Throw.isBusinessException("请选择持卡人证件有效期");
            }

            if (CertValidityTypeEnum.NO.getValue().equals(certValidityType)) {
                String certBeginDate = businessEnterApplyDto.getCertBeginDate();
                String certEndDate = businessEnterApplyDto.getCertEndDate();
                if (StringUtils.isBlank(certBeginDate)) {
                    Throw.isBusinessException("请选择持卡人证件有效期开始日期");
                }

                if (StringUtils.isBlank(certEndDate)) {
                    Throw.isBusinessException("请选择持卡人证件有效期截止日期");
                }

                LocalDate certBeginLocalDate = null;
                LocalDate certEndLocalDate = null;
                try {
                    certBeginLocalDate = LocalDateUtil.toLocalDate(certBeginDate, Constant.YYYY_MM_DD);
                } catch (Exception e) {
                    Throw.isBusinessException("持卡人证件有效期开始日期选择错误");
                }

                try {
                    certEndLocalDate = LocalDateUtil.toLocalDate(certEndDate, Constant.YYYY_MM_DD);
                } catch (Exception e) {
                    Throw.isBusinessException("持卡人证件有效期截止日期选择错误");
                }

                if (certEndLocalDate.compareTo(certBeginLocalDate) <= 0) {
                    Throw.isBusinessException("持卡人证件有效期截止日期必须大于开始日期");
                }
            }


            if (StringUtils.isBlank(businessEnterApplyDto.getSettleCardFrontPic()) || StringUtils.isBlank(businessEnterApplyDto.getSettleCardFrontPicUrl())) {
                Throw.isBusinessException("请上传银行卡正面");
            }

            if (StringUtils.isBlank(businessEnterApplyDto.getSettleCertFrontPic()) || StringUtils.isBlank(businessEnterApplyDto.getSettleCertFrontPicUrl())) {
                Throw.isBusinessException("请上传持卡人身份证人像面");
            }

            if (StringUtils.isBlank(businessEnterApplyDto.getSettleCertBackPic()) || StringUtils.isBlank(businessEnterApplyDto.getSettleCertBackPicUrl())) {
                Throw.isBusinessException("请上传持卡人身份证国徽面");
            }

            String mp = businessEnterApplyDto.getMp();
            if (StringUtils.isBlank(mp)) {
                Throw.isBusinessException("请输入银行卡绑定手机号");
            }
        }

        String cardName = businessEnterApplyDto.getCardName();
        if (StringUtils.isBlank(cardName)) {
            Throw.isBusinessException("请输入账户名称");
        }

        String cardNo = businessEnterApplyDto.getCardNo();
        if (StringUtils.isBlank(cardNo)) {
            Throw.isBusinessException("请输入银行账号");
        }

        String bankCode = businessEnterApplyDto.getBankCode();
        if (StringUtils.isBlank(bankCode)) {
            Throw.isBusinessException("请选择所属银行");
        }

        HfBankIdEnum hfBankIdEnum = HfBankIdEnum.typeOfValue(bankCode);
        if (hfBankIdEnum == null) {
            Throw.isBusinessException("所属银行不支持");
        }

        String bankProvinceName = businessEnterApplyDto.getBankProvinceName();
        String bankProvinceCode = businessEnterApplyDto.getBankProvinceCode();
        String bankCityName = businessEnterApplyDto.getBankCityName();
        String bankCityCode = businessEnterApplyDto.getBankCityCode();
        String bankCountyName = businessEnterApplyDto.getBankCountyName();
        String bankCountyCode = businessEnterApplyDto.getBankCountyCode();
        if (StringUtils.isBlank(bankProvinceName) || StringUtils.isBlank(bankProvinceCode)) {
            Throw.isBusinessException("请选择银行卡所在地省份");
        }

        if (StringUtils.isBlank(bankCityName) || StringUtils.isBlank(bankCityCode)) {
            Throw.isBusinessException("请选择银行卡所在地市");
        }

        if (StringUtils.isBlank(bankCountyName) || StringUtils.isBlank(bankCountyCode)) {
            Throw.isBusinessException("请选择银行卡所在地区县");
        }
    }

    @Override
    public List<BusinessEnterApplyPageVo> listByApplyNoAndHfId(String hfApplyNo, String hfMerchantNo) {
        return baseMapper.listByApplyNoAndHfId(hfApplyNo, hfMerchantNo);
    }

    @Override
    public Boolean updateBusinessEnterApplyById(BusinessEnterApplyUpdateDto businessEnterApplyUpdateDto) {
        TbBusinessEnterApplyPo tbBusinessEnterApplyPo = baseMapper.selectById(businessEnterApplyUpdateDto.getId());
        if (tbBusinessEnterApplyPo == null) {
            Throw.isBusinessException("未找到商家入驻信息");
        }

        BeanUtils.copyProperties(businessEnterApplyUpdateDto, tbBusinessEnterApplyPo);
        tbBusinessEnterApplyPo.setUpdateTime(LocalDateTime.now());
        int update = baseMapper.updateById(tbBusinessEnterApplyPo);
        if (update == 0) {
            Throw.isBusinessException("更新商家入驻信息失败");
        }

        return true;
    }

    @Override
    public Boolean merchantOpen(MerchantOpenDto merchantOpenDto) {
        TbBusinessEnterApplyPo tbBusinessEnterApplyPo = baseMapper.selectById(merchantOpenDto.getId());
        if (tbBusinessEnterApplyPo == null) {
            Throw.isBusinessException("未找到商家入驻记录数据");
        }

        Integer auditState = tbBusinessEnterApplyPo.getAuditState();
        Integer systemAuditState = tbBusinessEnterApplyPo.getSystemAuditState();

        // 只针对状态=待审核，汇付基本信息入驻审核成功或汇付商户业务开通审核拒绝 才可以调用
        if (!AuditStateEnum.WAIT_AUDIT.getValue().equals(auditState)
                || (!SystemAuditStateEnum.HF_ENTER_AUDIT_SUCCESS.getValue().equals(systemAuditState)
                && !SystemAuditStateEnum.HF_OPEN_AUDIT_FAIL.getValue().equals(systemAuditState))) {
            Throw.isBusinessException("只能手动开通待审核的汇付基本信息入驻审核成功或审核拒绝的商家入驻数据");
        }

        // 调用类型：1-接口开通，2-汇付控台开通
        Integer callState = merchantOpenDto.getCallState();
        if (callState == null) {
            Throw.isBusinessException("请选择调用类型");
        }

        if (callState == 1) {
            // 调用商户业务开通接口去开通相关业务
            HfBusinessEnterApply hfBusinessEnterApply = new HfBusinessEnterApply();
            org.springframework.beans.BeanUtils.copyProperties(tbBusinessEnterApplyPo, hfBusinessEnterApply);
            HfBusinessEnterOpenResult hfBusinessEnterOpenResult = hfApi.merchantOpen(hfBusinessEnterApply).unpack();
            if (StringUtils.isBlank(hfBusinessEnterOpenResult.getHuiFuId())) {
                log.error("汇付审核商家入驻成功，调用商户业务开通接口失败，调用接口result：{}", hfBusinessEnterOpenResult.getResultData());

                // 调用商户业务开通接口失败，系统审核状态=汇付基本信息入驻审核成功，管理后台核验处理后并再次申请调用
                Throw.isBusinessException("手动开通商户业务失败，原因：" + hfBusinessEnterOpenResult.getRespDesc());
            }

            BusinessEnterApplyUpdateDto businessEnterApplyUpdateDto = new BusinessEnterApplyUpdateDto();
            businessEnterApplyUpdateDto.setId(tbBusinessEnterApplyPo.getId());
            // 调用商户业务开通接口成功，系统审核状态=汇付商户业务开通待审核
            businessEnterApplyUpdateDto.setSystemAuditState(SystemAuditStateEnum.HF_OPEN_WAIT_AUDIT.getValue());
            boolean update = updateBusinessEnterApplyById(businessEnterApplyUpdateDto);
            if (!update) {
                Throw.isBusinessException("手动开通商户业务失败");
            }
        } else {
            // 根据手机号判断入驻的商家是否已经存在商户账号，如果存在，则不需要开通子账号业务，更新审核成功即可
            List<TbMerchantPo> tbMerchantPos = merchantMapper.selectList(new QueryWrapper<TbMerchantPo>().eq("del_state", 0)
                    .eq("mobile", tbBusinessEnterApplyPo.getMobile()));
            if (!CollectionUtils.isEmpty(tbMerchantPos)) {
                // 存在商户账号，不需要开通子账号业务，更新审核成功即可
                tbBusinessEnterApplyPo.setAuditState(AuditStateEnum.SUCCESS.getValue());
                tbBusinessEnterApplyPo.setUpdateTime(LocalDateTime.now());
                baseMapper.updateById(tbBusinessEnterApplyPo);

                // 发送mq消息处理，异步处理商家入驻成功之后商家账号创建和绑定
                log.info("手动开通商户业务成功，已经存在商户账号，不需要再次开通子账号业务，发送mq消息处理，异步处理商家入驻成功之后商家账号创建和绑定");
                businessEnterMsgProvider.sendMsg(tbBusinessEnterApplyPo.getId());
            } else {
                // 调用子账号开通接口
                HfBusinessEnterApply hfBusinessEnterApply = new HfBusinessEnterApply();
                org.springframework.beans.BeanUtils.copyProperties(tbBusinessEnterApplyPo, hfBusinessEnterApply);
                HfBusinessEnterOpenResult hfBusinessEnterOpenResult = hfApi.merchantSettleConfig(hfBusinessEnterApply).unpack();
                if (StringUtils.isBlank(hfBusinessEnterOpenResult.getApplyNo())
                        || StringUtils.isBlank(hfBusinessEnterOpenResult.getHuiFuId())) {
                    log.error("手动开通商户业务失败，调用子账号开通接口失败，调用接口result：{}", hfBusinessEnterOpenResult.getResultData());

                    Throw.isBusinessException("手动开通商户业务失败，调用子账号开通接口失败，原因：" + hfBusinessEnterOpenResult.getRespDesc());
                }

                // 调用子账号开通接口成功，系统审核状态=子账户待开通
                BusinessEnterApplyUpdateDto businessEnterApplyUpdateDto = new BusinessEnterApplyUpdateDto();
                businessEnterApplyUpdateDto.setId(tbBusinessEnterApplyPo.getId());
                businessEnterApplyUpdateDto.setSystemAuditState(SystemAuditStateEnum.SUB_ACCOUNT_WAIT_OPEN.getValue());
                businessEnterApplyUpdateDto.setHfAcctId(hfBusinessEnterOpenResult.getHfAcctId());
                boolean update = updateBusinessEnterApplyById(businessEnterApplyUpdateDto);
                if (!update) {
                    log.error("手动开通商户业务失败，更新系统审核状态=子账户待开通失败");
                    Throw.isBusinessException("手动开通商户业务失败");
                }
            }
        }

        return true;
    }

    @Override
    public Boolean merchantSubAcctOpen(MerchantSubAcctOpenDto merchantSubAcctOpenDto) {
        TbBusinessEnterApplyPo tbBusinessEnterApplyPo = baseMapper.selectById(merchantSubAcctOpenDto.getId());
        if (tbBusinessEnterApplyPo == null) {
            Throw.isBusinessException("未找到商家入驻记录数据");
        }

        Integer auditState = tbBusinessEnterApplyPo.getAuditState();
        Integer systemAuditState = tbBusinessEnterApplyPo.getSystemAuditState();

        // 只针对状态=待审核，汇付商户业务开通成功或子账户开通审核拒绝 才可以调用
        if (!AuditStateEnum.WAIT_AUDIT.getValue().equals(auditState)
                || (!SystemAuditStateEnum.HF_OPEN_SUCCESS.getValue().equals(systemAuditState)
                && !SystemAuditStateEnum.SUB_ACCOUNT_OPEN_AUDIT_FAIL.getValue().equals(systemAuditState))) {
            Throw.isBusinessException("只能手动开通待审核的汇付商户业务开通成功或子账户开通审核拒绝的商家入驻数据");
        }

        // 根据手机号判断入驻的商家是否已经存在商户账号，如果存在，则不需要开通子账号业务，更新审核成功即可
        List<TbMerchantPo> tbMerchantPos = merchantMapper.selectList(new QueryWrapper<TbMerchantPo>().eq("del_state", 0)
                .eq("mobile", tbBusinessEnterApplyPo.getMobile()));
        if (!CollectionUtils.isEmpty(tbMerchantPos)) {
            // 存在商户账号，不需要开通子账号业务，更新审核成功即可
            tbBusinessEnterApplyPo.setAuditState(AuditStateEnum.SUCCESS.getValue());
            tbBusinessEnterApplyPo.setUpdateTime(LocalDateTime.now());
            baseMapper.updateById(tbBusinessEnterApplyPo);

            // 发送mq消息处理，异步处理商家入驻成功之后商家账号创建和绑定
            log.info("手动开通子账号成功，已经存在商户账号，不需要再次开通子账号业务，发送mq消息处理，异步处理商家入驻成功之后商家账号创建和绑定");
            businessEnterMsgProvider.sendMsg(tbBusinessEnterApplyPo.getId());
        } else {
            // 调用子账号开通接口
            HfBusinessEnterApply hfBusinessEnterApply = new HfBusinessEnterApply();
            org.springframework.beans.BeanUtils.copyProperties(tbBusinessEnterApplyPo, hfBusinessEnterApply);
            HfBusinessEnterOpenResult hfBusinessEnterOpenResult = hfApi.merchantSettleConfig(hfBusinessEnterApply).unpack();
            if (StringUtils.isBlank(hfBusinessEnterOpenResult.getApplyNo())
                    || StringUtils.isBlank(hfBusinessEnterOpenResult.getHuiFuId())) {
                if ("成功".equals(hfBusinessEnterOpenResult.getRespDesc())) {
                    return true;
                }

                log.error("手动开通子账号失败，调用子账号开通接口失败，调用接口result：{}", hfBusinessEnterOpenResult.getResultData());

                Throw.isBusinessException("手动开通子账号失败，原因：" + hfBusinessEnterOpenResult.getRespDesc());
            }

            // 调用子账号开通接口成功，系统审核状态=子账户待开通
            BusinessEnterApplyUpdateDto businessEnterApplyUpdateDto = new BusinessEnterApplyUpdateDto();
            businessEnterApplyUpdateDto.setId(tbBusinessEnterApplyPo.getId());
            businessEnterApplyUpdateDto.setSystemAuditState(SystemAuditStateEnum.SUB_ACCOUNT_WAIT_OPEN.getValue());
            businessEnterApplyUpdateDto.setHfAcctId(hfBusinessEnterOpenResult.getHfAcctId());
            boolean update = updateBusinessEnterApplyById(businessEnterApplyUpdateDto);
            if (!update) {
                log.error("手动开通子账号失败，更新系统审核状态=子账户待开通失败");
                Throw.isBusinessException("手动开通子账号失败");
            }
        }

        return true;
    }

    @Override
    public BusinessEnterApplyVo getEnterInfoByUserId(Long userId) {
        List<TbBusinessEnterApplyPo> tbBusinessEnterApplyPos = baseMapper.selectList(new QueryWrapper<TbBusinessEnterApplyPo>().eq("del_state", 0)
                .eq("user_id", userId).orderByDesc("apply_time"));
        if (!CollectionUtils.isEmpty(tbBusinessEnterApplyPos)) {
            TbBusinessEnterApplyPo tbBusinessEnterApplyPo = tbBusinessEnterApplyPos.get(0);
            BusinessEnterApplyVo businessEnterApplyVo = new BusinessEnterApplyVo();
            BeanUtils.copyProperties(tbBusinessEnterApplyPo, businessEnterApplyVo);

            Integer auditState = tbBusinessEnterApplyPo.getAuditState();
            Integer systemAuditState = tbBusinessEnterApplyPo.getSystemAuditState();
            // 审核状态=待认证，且是系统审核状态=汇付商户业务开通成功 或 微信实名待认证 或 合同待签约，需要返回授权二维码
            if (AuditStateEnum.WAIT_AUTH.getValue().equals(auditState)
                    && (SystemAuditStateEnum.HF_OPEN_SUCCESS.getValue().equals(systemAuditState)
                    || SystemAuditStateEnum.WX_REAL_WAIT_AUTH.getValue().equals(systemAuditState)
                    || SystemAuditStateEnum.CONTRACT_WAIT_SIGN.getValue().equals(systemAuditState))) {

                if (SystemAuditStateEnum.CONTRACT_WAIT_SIGN.getValue().equals(systemAuditState)) {
                    businessEnterApplyVo.setQrCodeAuthState(true);
                }

                if (SystemAuditStateEnum.WX_REAL_WAIT_AUTH.getValue().equals(systemAuditState)) {
                    businessEnterApplyVo.setAgreementSignState(true);
                }

                String hfMerchantNo = tbBusinessEnterApplyPo.getHfMerchantNo();
                String regResultListStr = redisUtil.get(String.format(RedisKeyConstant.HF_WX_OPEN_RESULT_KEY, hfMerchantNo));
                if (!StringUtils.isBlank(regResultListStr)) {
                    JSONArray jsonArray = JSON.parseArray(regResultListStr);
                    JSONObject jsonObject = jsonArray.getJSONObject(0);
                    // 授权二维码
                    businessEnterApplyVo.setQrCodeData(jsonObject.getString("qrcode_data"));
                    // 协议签署连接
//                    businessEnterApplyVo.setAgreementLink(jsonObject.getString("agreement_link"));
                }

                Integer signUserType = tbBusinessEnterApplyPo.getSignUserType();
                if (SignUserTypeEnum.LEGAL.getValue().equals(signUserType)) {
                    businessEnterApplyVo.setAgreementLink(PrivacyUtil.encryptMobile(tbBusinessEnterApplyPo.getLegalMobileNo()));
                } else {
                    businessEnterApplyVo.setAgreementLink(PrivacyUtil.encryptMobile(tbBusinessEnterApplyPo.getContactMobileNo()));
                }
            }

            return businessEnterApplyVo;
        }

        return null;
    }

    @Override
    public List<BusinessEnterApplyPageVo> listByHfId(String hfMerchantNo) {
        return baseMapper.listByHfId(hfMerchantNo);
    }

    @Override
    public List<BusinessEnterApplyPageVo> listByDto(BusinessEnterApplyQueryDto businessEnterApplyQueryDto) {
        return baseMapper.listByDto(businessEnterApplyQueryDto);
    }

    @Override
    public Boolean scanBusinessEnter() {
        // 查询审核状态=待认证的商家入驻数据
        List<TbBusinessEnterApplyPo> businessEnterApplyPos = baseMapper.selectList(new QueryWrapper<TbBusinessEnterApplyPo>().eq("del_state", 0)
                .eq("audit_state", AuditStateEnum.WAIT_AUTH.getValue()));
        if (CollectionUtils.isEmpty(businessEnterApplyPos)) {
            businessEnterApplyPos = baseMapper.selectList(new QueryWrapper<TbBusinessEnterApplyPo>().eq("del_state", 0)
                    .eq("audit_state", AuditStateEnum.WAIT_AUDIT.getValue())
                    .in("system_audit_state", Arrays.asList(SystemAuditStateEnum.HF_OPEN_WAIT.getValue(), SystemAuditStateEnum.HF_OPEN_WAIT_AUDIT.getValue())));
            if (CollectionUtils.isEmpty(businessEnterApplyPos)) {
                return true;
            }
        }

        LocalDateTime now = LocalDateTime.now();
        for (TbBusinessEnterApplyPo businessEnterApplyPo : businessEnterApplyPos) {
            String hfMerchantNo = businessEnterApplyPo.getHfMerchantNo();
            Integer systemAuditState = businessEnterApplyPo.getSystemAuditState();

//            // 合同签约状态
//            boolean signState = false;
//            // 微信实名状态
//            boolean authState = false;

            // 如果系统审核状态=汇付商户业务开通成功，则查询签约状态和微信实名状态
            if (SystemAuditStateEnum.HF_OPEN_SUCCESS.getValue().equals(systemAuditState) || SystemAuditStateEnum.HF_OPEN_WAIT.getValue().equals(systemAuditState)) {
                // 查询签约状态
                JSONObject merchantBasicDataQueryJSONObject = hfApi.merchantBasicDataQuery(hfMerchantNo).unpack();
                if (merchantBasicDataQueryJSONObject != null) {
                    JSONObject dataJSONObject = merchantBasicDataQueryJSONObject.getJSONObject("data");
                    // 协议信息
                    JSONArray agreementInfoListJSONArray = dataJSONObject.getJSONArray("agreement_info_list");
                    if (agreementInfoListJSONArray != null && agreementInfoListJSONArray.size() > 0) {
                        JSONObject agreementInfoListJSONObject = agreementInfoListJSONArray.getJSONObject(0);
                        // 合同状态	电子协议类型会返回以下值：2：创建合同异常  3：待签约 4：签约中 5：签约完成(电子协议只有签约完成才能做交易) 6：已失效 7：已拒签 8：签约失败
                        String conStat = agreementInfoListJSONObject.getString("con_stat");
                        if (!org.springframework.util.StringUtils.isEmpty(conStat)) {
                            if ("5".equals(conStat)) {
                                // 签约完成
//                                signState = true;
                                signAndAuthSuccess(now, businessEnterApplyPo, hfMerchantNo);
                            } else if ("7".equals(conStat) || "8".equals(conStat)) {
                                // 已拒签或签约失败，审核失败，让用户重新申请
                                businessEnterApplyPo.setAuditState(AuditStateEnum.FAIL.getValue());
                                businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.CONTRACT_WAIT_SIGN_FAIL.getValue());
                                businessEnterApplyPo.setHfFailReason(JSON.toJSONString(agreementInfoListJSONArray));
                                businessEnterApplyPo.setUpdateTime(now);

                                int update = baseMapper.updateById(businessEnterApplyPo);
//                                if (update > 0) {
                                // 审核拒绝，发送入驻失败短信
//                                    smsBiz.sendEnterFailSms(businessEnterApplyPo.getBusinessName(), businessEnterApplyPo.getMobile());
//                                }
//                                continue;
                            }
                        }
                    }
                }

                // 查询微信实名状态
//                JSONObject wxBusinessRealQueryJSOObject = hfApi.wxBusinessRealQuery(hfMerchantNo).unpack();
//                if (wxBusinessRealQueryJSOObject != null) {
//                    JSONObject dataJSONObject = wxBusinessRealQueryJSOObject.getJSONObject("data");
//                    // 实名授权状态	    授权状态 1：授权成功；0：授权失败；
//                    String authorizeStat = dataJSONObject.getString("authorize_stat");
//                    if (!org.springframework.util.StringUtils.isEmpty(authorizeStat)) {
//                        if ("1".equals(authorizeStat)) {
//                            // 授权成功
//                            authState = true;
//                        } else if ("0".equals(authorizeStat)) {
//                            // 授权失败，审核失败，让用户重新申请
//                            businessEnterApplyPo.setAuditState(AuditStateEnum.FAIL.getValue());
//                            businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.WX_REAL_WAIT_AUTH_FAIL.getValue());
//                            businessEnterApplyPo.setHfFailReason(JSON.toJSONString(wxBusinessRealQueryJSOObject));
//                            businessEnterApplyPo.setUpdateTime(now);
//
//                            baseMapper.updateById(businessEnterApplyPo);
//                            continue;
//                        }
//                    }
//                }
//
//                // 微信实名成功+合同签约成功
//                if (signState && authState) {
//                    signAndAuthSuccess(now, businessEnterApplyPo, hfMerchantNo);
//                    continue;
//                }
//
//                if (signState) {
//                    // 合同签约成功，修改系统审核状态=微信实名待认证
//                    businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.WX_REAL_WAIT_AUTH.getValue());
//                    businessEnterApplyPo.setUpdateTime(now);
//                    baseMapper.updateById(businessEnterApplyPo);
//                    continue;
//                }
//
//                if (authState) {
//                    // 实名认证成功，修改系统审核状态=合同待签约
//                    businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.CONTRACT_WAIT_SIGN.getValue());
//                    businessEnterApplyPo.setUpdateTime(now);
//                    baseMapper.updateById(businessEnterApplyPo);
//                    continue;
//                }
//
//                continue;
            }

            // 如果系统审核状态=微信实名待认证，则查询微信实名状态
//            if (SystemAuditStateEnum.WX_REAL_WAIT_AUTH.getValue().equals(systemAuditState)) {
//                // 查询微信实名状态
//                JSONObject wxBusinessRealQueryJSOObject = hfApi.wxBusinessRealQuery(hfMerchantNo).unpack();
//                if (wxBusinessRealQueryJSOObject != null) {
//                    JSONObject dataJSONObject = wxBusinessRealQueryJSOObject.getJSONObject("data");
//                    // 实名授权状态	    授权状态 1：授权成功；0：授权失败；
//                    String authorizeStat = dataJSONObject.getString("authorize_stat");
//                    if (!org.springframework.util.StringUtils.isEmpty(authorizeStat)) {
//                        if ("1".equals(authorizeStat)) {
//                            // 授权成功
//                            signAndAuthSuccess(now, businessEnterApplyPo, hfMerchantNo);
//                        } else if ("0".equals(authorizeStat)) {
//                            // 授权失败，审核失败，让用户重新申请
//                            businessEnterApplyPo.setAuditState(AuditStateEnum.FAIL.getValue());
//                            businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.WX_REAL_WAIT_AUTH_FAIL.getValue());
//                            businessEnterApplyPo.setHfFailReason(JSON.toJSONString(wxBusinessRealQueryJSOObject));
//                            businessEnterApplyPo.setUpdateTime(now);
//
//                            baseMapper.updateById(businessEnterApplyPo);
//                            continue;
//                        }
//                    }
//                }
//
//            }
//
//            // 如果系统审核状态=合同待签约，则查询合同签约状态
//            if (SystemAuditStateEnum.CONTRACT_WAIT_SIGN.getValue().equals(systemAuditState)) {
//                // 查询合同签约状态
//                JSONObject merchantBasicDataQueryJSONObject = hfApi.merchantBasicDataQuery(hfMerchantNo).unpack();
//                if (merchantBasicDataQueryJSONObject != null) {
//                    JSONObject dataJSONObject = merchantBasicDataQueryJSONObject.getJSONObject("data");
//                    // 协议信息
//                    JSONArray agreementInfoListJSONArray = dataJSONObject.getJSONArray("agreement_info_list");
//                    if (agreementInfoListJSONArray != null && agreementInfoListJSONArray.size() > 0) {
//                        JSONObject agreementInfoListJSONObject = agreementInfoListJSONArray.getJSONObject(0);
//                        // 合同状态	电子协议类型会返回以下值：2：创建合同异常  3：待签约 4：签约中 5：签约完成(电子协议只有签约完成才能做交易) 6：已失效 7：已拒签 8：签约失败
//                        String conStat = agreementInfoListJSONObject.getString("con_stat");
//                        if (!org.springframework.util.StringUtils.isEmpty(conStat)) {
//                            if ("5".equals(conStat)) {
//                                // 签约完成
//                                signAndAuthSuccess(now, businessEnterApplyPo, hfMerchantNo);
//                            } else if ("7".equals(conStat) || "8".equals(conStat)) {
//                                // 已拒签或签约失败，审核失败，让用户重新申请
//                                businessEnterApplyPo.setAuditState(AuditStateEnum.FAIL.getValue());
//                                businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.CONTRACT_WAIT_SIGN_FAIL.getValue());
//                                businessEnterApplyPo.setHfFailReason(JSON.toJSONString(agreementInfoListJSONArray));
//                                businessEnterApplyPo.setUpdateTime(now);
//
//                                baseMapper.updateById(businessEnterApplyPo);
//                            }
//                        }
//                    }
//                }
//            }
        }

        return true;
    }

    private void signAndAuthSuccess(LocalDateTime now, TbBusinessEnterApplyPo businessEnterApplyPo, String hfMerchantNo) {
        // 审核状态=待审核，系统审核状态=签约成功
        businessEnterApplyPo.setAuditState(AuditStateEnum.WAIT_AUDIT.getValue());
        businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.SIGN_SUCCESS.getValue());
        businessEnterApplyPo.setUpdateTime(now);

        // 删除redis缓存
        redisUtil.del(String.format(RedisKeyConstant.HF_WX_OPEN_RESULT_KEY, hfMerchantNo));

        // 根据手机号判断入驻的商家是否已经存在商户账号，如果存在，则不需要开通子账号业务，更新审核成功即可
        List<TbMerchantPo> tbMerchantPos = merchantMapper.selectList(new QueryWrapper<TbMerchantPo>().eq("del_state", 0)
                .eq("mobile", businessEnterApplyPo.getMobile()));
        if (!CollectionUtils.isEmpty(tbMerchantPos)) {
            // 存在商户账号，不需要开通子账号业务，更新审核成功即可
            businessEnterApplyPo.setAuditState(AuditStateEnum.SUCCESS.getValue());
            businessEnterApplyPo.setUpdateTime(now);
            baseMapper.updateById(businessEnterApplyPo);

            // 发送mq消息处理，异步处理商家入驻成功之后商家账号创建和绑定
            log.info("发送mq消息处理，异步处理商家入驻成功之后商家账号创建和绑定");
            businessEnterMsgProvider.sendMsg(businessEnterApplyPo.getId());
        } else {
            // 调用子账号开通接口去开通相关业务
            HfBusinessEnterApply hfBusinessEnterApply = new HfBusinessEnterApply();
            BeanUtils.copyProperties(businessEnterApplyPo, hfBusinessEnterApply);
            HfBusinessEnterOpenResult hfBusinessEnterOpenResult = hfApi.merchantSettleConfig(hfBusinessEnterApply).unpack();
            if (StringUtils.isBlank(hfBusinessEnterOpenResult.getApplyNo())
                    || StringUtils.isBlank(hfBusinessEnterOpenResult.getHuiFuId())) {
                log.error("汇付审核商家入驻成功，调用子账号开通接口失败，调用接口result：{}", hfBusinessEnterOpenResult.getResultData());

                // 调用子账号开通接口失败，系统审核状态=汇付商户业务开通成功，管理后台核验处理后并再次申请调用
                businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.HF_OPEN_SUCCESS.getValue());
                businessEnterApplyPo.setHfFailReason(hfBusinessEnterOpenResult.getRespDesc());
            } else {
                // 调用子账号开通接口成功，系统审核状态=子账户待开通
                businessEnterApplyPo.setSystemAuditState(SystemAuditStateEnum.SUB_ACCOUNT_WAIT_OPEN.getValue());
                businessEnterApplyPo.setHfAcctId(hfBusinessEnterOpenResult.getHfAcctId());
            }

            businessEnterApplyPo.setUpdateTime(now);
            baseMapper.updateById(businessEnterApplyPo);
        }
    }

    @Override
    public BusinessEnterApplyDetailVo getSuccessEnterInfoByOpenid(String openid) {
        List<TbBusinessEnterApplyPo> businessEnterApplyPos = baseMapper.selectList(new QueryWrapper<TbBusinessEnterApplyPo>().eq("del_state", 0)
                .eq("audit_state", AuditStateEnum.SUCCESS.getValue())
                .eq("openid", openid).orderByDesc("apply_time"));
        if (!CollectionUtils.isEmpty(businessEnterApplyPos)) {
            BusinessEnterApplyDetailVo businessEnterApplyDetailVo = new BusinessEnterApplyDetailVo();
            BeanUtils.copyProperties(businessEnterApplyPos.get(0), businessEnterApplyDetailVo);
            return businessEnterApplyDetailVo;
        }

        return null;
    }

    @Override
    public Boolean validSettleCode(String settleCode) {
        if (StringUtils.isBlank(settleCode)) {
            Throw.isBusinessException(10012, "二维码失效");
        }

        List<TbInviteBusinessUrlPo> tbInviteBusinessUrlPos = inviteBusinessUrlMapper.selectList(new QueryWrapper<TbInviteBusinessUrlPo>()
                .eq("del_state", 0)
                .eq("invite_code", settleCode));
        if (CollectionUtils.isEmpty(tbInviteBusinessUrlPos)) {
            Throw.isBusinessException(10012, "二维码失效");
        }

        TbInviteBusinessUrlPo tbInviteBusinessUrlPo = tbInviteBusinessUrlPos.get(0);
        if (!LocalDateTime.now().isBefore(tbInviteBusinessUrlPo.getExpireTime())) {
            Throw.isBusinessException(10012, "二维码失效");
        }

        return true;
    }
}
